<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
    #app {
      width: 100vw;
      height: 100vh;
    }
    .modal {
      display: flex;
      justify-content: center;
      align-items: center;
      position: fixed;
      width: 100vw;
      height: 100vh;
      top: 0;
      left: 0;
      background: rgba(0, 0, 0, .3);
    }
    .modal .mask {
      width: 400px;
      height: 300px;
      padding: 20px;
      background: lightgreen;
    }
  </style>
</head>
<body>
<div id="app">
  <button @click="openModal">打开</button>
  <modal :open="flag" @close="closeModal"></modal>
</div>

<template id="modalTpl">
  <div class="modal" v-show="open">
    <div class="mask">
      <button @click="shutdown">关闭</button>
    </div>
  </div>
</template>

<script src="../node_modules/vue/dist/vue.js"></script>
<script>
  let modal = {
    template: '#modalTpl',
    data() {
      return {}
    },
    props: ['open'],
    methods: {
      shutdown() {
        this.$emit('close', false);
      }
    }
  };

  let vm = new Vue({
    el: '#app',
    data: {
      flag: false
    },
    methods: {
      openModal() {
        this.flag = true;
      },
      closeModal() {
        this.flag = false;
      }
    },
    components: {
      modal
    }
  })
</script>
</body>
</html>